// 定义策略接口 `Strategy`，包含一个方法 `execute`，接受两个整数参数并返回一个整数结果。
trait Strategy {
    fn execute(&self, a: i32, b: i32) -> i32;
}

// 具体策略实现 `ConcreteStrategyA`，实现了 `Strategy` 接口。
struct ConcreteStrategyA;

impl Strategy for ConcreteStrategyA {
    // 实现 `execute` 方法，返回两个整数的加法结果。
    fn execute(&self, a: i32, b: i32) -> i32 {
        a + b
    }
}

// 具体策略实现 `ConcreteStrategyB`，实现了 `Strategy` 接口。
struct ConcreteStrategyB;

impl Strategy for ConcreteStrategyB {
    // 实现 `execute` 方法，返回两个整数的乘法结果。
    fn execute(&self, a: i32, b: i32) -> i32 {
        a * b
    }
}

// 环境类 `Context`，持有一个策略对象，并在需要时调用策略的方法。
struct Context {
    strategy: Box<dyn Strategy>, // 使用 Box<dyn Strategy> 存储策略对象
}

impl Context {
    // 构造函数 `new()`，初始化时传入一个实现了 `Strategy` 接口的具体策略对象。
    fn new(strategy: Box<dyn Strategy>) -> Self {
        Self { strategy }
    }

    // 设置策略的方法 `set_strategy()`，用于动态更改当前的策略对象。
    fn set_strategy(&mut self, strategy: Box<dyn Strategy>) {
        self.strategy = strategy; // 更新当前策略对象为传入的策略
    }

    // 执行策略的方法 `execute_strategy()`，调用当前策略对象的 `execute` 方法，并返回结果。
    fn execute_strategy(&self, a: i32, b: i32) -> i32 {
        self.strategy.execute(a, b) // 调用当前策略对象的 `execute` 方法
    }
}

// 主函数入口 `main()`，演示策略模式的使用。
pub fn main() {
    let mut context = Context::new(Box::new(ConcreteStrategyA)); // 创建一个 Context，并初始化为使用 ConcreteStrategyA

    println!("Result: {}", context.execute_strategy(3, 4)); // 输出策略执行的结果

    context.set_strategy(Box::new(ConcreteStrategyB)); // 切换策略为 ConcreteStrategyB
    println!("Result: {}", context.execute_strategy(3, 4)); // 输出切换后策略执行的结果
}
